﻿using System.Collections.Generic;
using System.Linq;
using log4net;
using SmallBusinessKit.DataAccess.Interfaces;
using SmallBusinessKit.Interfaces;
using SmallBusinessKit.Models.Entities;

namespace SmallBusinessKit.Domains
{
    /// <summary>
    /// SmallBusiness Business Logic Layer
    /// </summary>
    /// <remarks>
    /// Because this is such a tiny app, this domain just consolidates all the others. It's just here as an example.
    /// </remarks>
    public class SmallBusinessDomain : ISmallBusinessDomain
    {
        #region Properties

        private static readonly ILog _log = LogManager.GetLogger(typeof(SmallBusinessDomain));

        private readonly ICategoryRepository    _categoryRepository;
        private readonly IItemRepository        _itemRepository;
        private readonly IPersonRepository      _personRepository;
        private readonly INewsRepository        _newsRepository;
        private readonly ITestimonialRepository _testimonialRepository;

        #endregion

        #region Methods

        public SmallBusinessDomain(ICategoryRepository categoryRepository, IItemRepository itemRepository, IPersonRepository personRepository, INewsRepository newsRepository, ITestimonialRepository testimonialRepository)
        {
            _categoryRepository    = categoryRepository;
            _itemRepository        = itemRepository;
            _personRepository      = personRepository;
            _newsRepository        = newsRepository;
            _testimonialRepository = testimonialRepository;
        }

        public IEnumerable<Category> GetCategories(string id)
        {
            var results = _categoryRepository.GetMany(i => i.ParentId == id && i.IsVisible).ToList();

            _log.DebugFormat("Retrieved {0} Categories", results.Count);

            return (results);
        }

        public IEnumerable<Item> GetChildItems(string parentCategoryId)
        {
            var items = new List<Item>();

            var category = _categoryRepository.Get(i => i.Id == parentCategoryId && i.IsVisible);
            
            if (category.Items.Any())
            {
                items.AddRange(category.Items);
                _log.DebugFormat("Retrieved {0} Items", category.Items.Count);
            }

            return (items);
        }

        public Item GetItem(string id)
        {
            var item = _itemRepository.Get(i => i.Id == id);

            _log.DebugFormat("Retrieved Item Id {0} / {1}", item.Id, item.Title);

            return (item);
        }

        public IQueryable<Person> GetAllPersons()
        {
            var query = _personRepository.GetAsQueryable();

            _log.DebugFormat("Retrieved Query Expression: {0}", query.Expression);

            return (query);
        }

        public IEnumerable<News> GetAllNews()
        {
            var results = _newsRepository.GetMany(i => i.IsVisible).ToList();

            _log.DebugFormat("Retrieved {0} News articles", results.Count);

            results.ForEach(i => i.Content = i.Content.Substring(0, 256)); // just want abstracts for each on the News page...

            return (results);
        }

        public News GetNewsItem(string id)
        {
            var result = _newsRepository.Get(i => i.Id == id);
            // or...
            // var result = _newsRepository.GetById(id);

            _log.DebugFormat("Retrieved News Id {0} / {1}", result.Id, result.Title);

            return (result);
        }

        public IEnumerable<Testimonial> GetAllTestimonials()
        {
            var results = _testimonialRepository.GetMany(i => i.IsVisible).ToList();

            _log.DebugFormat("Retrieved {0} Testimonials", results.Count);

            return (results);
        }

        #endregion
    }
}
